import type { UnConfig } from '@uni-helper/uni-network'
import { isString } from '@pmun/utils'
import un from '@uni-helper/uni-network'
import toutiaoConfig from '@/toutiao.config.json'
import weixinConfig from '@/weixin.config.json'
import { handleError, handleResponseAuth } from './helper'
import { Loading } from './loading'

const { VITE_APP_API_BASE_URL, VITE_APP_API_PREFIX } = import.meta.env

interface HttpMeta {
  /** 是否登录 */
  auth?: boolean
  /** 是否展示错误信息 */
  toast?: boolean
  /** 是否走catch */
  catch?: boolean
}

/**
 * @see 文档：https://uni-network.netlify.app/
 */
export const instance = un.create({
  loading: true,
})

const loading = new Loading()

// 请求拦截器
instance.interceptors.request.use((config) => {
  const userPinia = useUserPinia()
  const token = userPinia.getToken
  let baseURL = VITE_APP_API_BASE_URL
  // #ifdef H5
  baseURL = VITE_APP_API_PREFIX || VITE_APP_API_BASE_URL
  // #endif
  config.baseUrl = config.baseUrl || baseURL
  config.headers = Object.assign({}, config.headers || {})
  config.headers.saasId = 0
  // #ifdef MP-WEIXIN
  if (weixinConfig.saasid) config.headers.saasId = weixinConfig.saasid
  // #endif
  // #ifdef MP-TOUTIAO
  if (toutiaoConfig.saasid) config.headers.saasId = toutiaoConfig.saasid
  // #endif
  if (config.meta) {
    if (config?.meta?.auth && token) {
      config.headers.token = token
      config.headers.Authorization = `Bearer ${token}`
    }
  }
  loading.show(config.loading)
  return config
})

instance.interceptors.response.use((response: any) => {
  const { errno } = response
  if (errno) {
    showToast('服务器出错，请稍后再试。')
    loading?.hide(true)
    return Promise.reject(response)
  }
  loading?.hide(response.config.loading)
  // TODO 返回数据根据业务需求修改
  if (isString(response.data)) {
    response.data = JSON.parse(response.data)
  }
  const { code, msg } = response.data
  if ([1, 200].includes(code)) return response.data
  if ([401].includes(code)) {
    handleResponseAuth()
    return new Promise(() => { })
  }
  handleError(response)
  if (response.config.meta.toast !== false) {
    showToast(msg || '请求失败！请您稍后重试')
  }
  if (response.config.meta.catch === false) return new Promise(() => { })
  return Promise.reject(response.data)
}, (error) => {
  loading?.hide(error.config.loading)
  return Promise.reject(error)
})

type RequestData = Record<string, any>

/**
 * 预设的请求数据类型和响应数据类型
 * 泛型内数据类型：<响应数据类型, 请求数据类型>，可不传，默认为 <Record<string, any>, Record<string, any>>
 */
export function request<T, D = RequestData>(
  url: string,
  config?: UnConfig<T, D>,
  meta?: HttpMeta,
) {
  return instance.request<T, D, T>({ url, ...config, meta })
}

export function upload<T, D = RequestData>(
  url: string,
  config?: UnConfig<T, D>,
  meta?: HttpMeta,
): Promise<T> {
  return instance.upload({ url, ...config, meta })
}
